package main

import (
	"fmt"
	"math/rand"
	"time"
)

func main() {
	ch := make(chan int, 10)
	done := make(chan bool)

	rand.New(rand.NewSource(time.Now().Unix()))

	// 随机生产者/消费者数量 1-3 个
	baseCount := 1
	maxCount := 3
	producer := baseCount + rand.Intn(maxCount-baseCount)
	consumer := baseCount + rand.Intn(maxCount-baseCount)

	fmt.Println("producer: ", producer)
	fmt.Println("consumer: ", consumer)

	// 生产者，每间隔 1-5 秒生产一次
	for i := 0; i < producer; i++ {
		go func(ch chan<- int, i int) {
			ticker := time.NewTicker(time.Second)
			defer ticker.Stop()
			for {
				sleepTime := 1 + rand.Intn(4)
				fmt.Printf("生产者%d号正在休息%ds\n", i, sleepTime)
				ticker.Reset(time.Second * time.Duration(sleepTime))
				select {
				case <-done:
					fmt.Printf("生产者%d结束\n", i)
					return
				case <-ticker.C:
					fmt.Printf("生产者%d号正在生产\n", i)
					ch <- i
					fmt.Printf("生产者%d号正在完成生产\n", i)
				}
			}
		}(ch, i)
	}

	// 消费者，每间隔 1-5 秒消费一次
	for i := 0; i < consumer; i++ {
		go func(ch <-chan int, i int) {
			ticker := time.NewTicker(time.Second)
			defer ticker.Stop()
			for {
				sleepTime := 1 + rand.Intn(4)
				fmt.Printf("消费者%d正在休息%ds\n", i, sleepTime)
				ticker.Reset(time.Second * time.Duration(sleepTime))
				select {
				case <-done:
					fmt.Printf("消费者%d结束\n", i)
					return
				case <-ticker.C:
					fmt.Printf("消费者%d正在消费\n", i)
					x := <-ch
					fmt.Printf("消费者%d完成消费%d\n", i, x)
				}
			}

		}(ch, i)
	}

	// 主线程阻塞住
	//time.Sleep(time.Second * time.Duration(producer*consumer))
	time.Sleep(time.Second * 60)
	// 通知结束
	close(done)
	time.Sleep(time.Second * 1)
	fmt.Println("主线程退出")
}
